#-------------------------------------------------------------------------------
# Name:        OlsIoctl
# Purpose:     WinRing0.sys DeviceIoControl code
#
# Author:      SUPER_紫电  QQ:911344755
#
# Created:     15/08/2022
# Copyright:   (c) SUPER_紫电 2022 All rights reserved.
# Licence:     <Modified BSD License>
#-------------------------------------------------------------------------------

from ctypes import Structure, Union, c_ubyte
from ctypes.wintypes import LARGE_INTEGER, ULARGE_INTEGER, USHORT, ULONG
from winioctlcon import CTL_CODE, METHOD_BUFFERED, FILE_ANY_ACCESS, \
    FILE_READ_ACCESS, FILE_WRITE_ACCESS

UCHAR  = c_ubyte

#-----------------------------------------------------------------------------
#
# The Device type codes form 32768 to 65535 are for customer use.
#
#-----------------------------------------------------------------------------
OLS_TYPE = 40000

#-----------------------------------------------------------------------------
#
# Version Information
#
#-----------------------------------------------------------------------------
OLS_DRIVER_ID = "WinRing0_1_2_0"
OLS_DRIVER_MAJOR_VERSION = 1
OLS_DRIVER_MINOR_VERSION = 2
OLS_DRIVER_REVISION = 0
OLS_DRIVER_RELESE = 5
OLS_DRIVER_VERSION = (OLS_DRIVER_MAJOR_VERSION << 24)   \
    | (OLS_DRIVER_MINOR_VERSION << 16) | (OLS_DRIVER_REVISION << 8)    \
    | OLS_DRIVER_RELESE

#-----------------------------------------------------------------------------
#
# The IOCTL function codes from 0x800 to 0xFFF are for customer use.
#
#-----------------------------------------------------------------------------
IOCTL_OLS_GET_DRIVER_VERSION =     CTL_CODE(
    OLS_TYPE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS
)
IOCTL_OLS_GET_REFCOUNT = CTL_CODE(
    OLS_TYPE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS
)
IOCTL_OLS_READ_MSR = CTL_CODE(
    OLS_TYPE, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS
)
IOCTL_OLS_WRITE_MSR = CTL_CODE(
    OLS_TYPE, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS
)
IOCTL_OLS_READ_PMC = CTL_CODE(
    OLS_TYPE, 0x823, METHOD_BUFFERED, FILE_ANY_ACCESS
)
IOCTL_OLS_HALT = CTL_CODE(
    OLS_TYPE, 0x824, METHOD_BUFFERED, FILE_ANY_ACCESS
)
IOCTL_OLS_READ_IO_PORT = CTL_CODE(
    OLS_TYPE, 0x831, METHOD_BUFFERED, FILE_READ_ACCESS
)
IOCTL_OLS_WRITE_IO_PORT = CTL_CODE(
    OLS_TYPE, 0x832, METHOD_BUFFERED, FILE_WRITE_ACCESS
)
IOCTL_OLS_READ_IO_PORT_BYTE = CTL_CODE(
    OLS_TYPE, 0x833, METHOD_BUFFERED, FILE_READ_ACCESS
)
IOCTL_OLS_READ_IO_PORT_WORD = CTL_CODE(
    OLS_TYPE, 0x834, METHOD_BUFFERED, FILE_READ_ACCESS
)
IOCTL_OLS_READ_IO_PORT_DWORD = CTL_CODE(
    OLS_TYPE, 0x835, METHOD_BUFFERED, FILE_READ_ACCESS
)
IOCTL_OLS_WRITE_IO_PORT_BYTE = CTL_CODE(
    OLS_TYPE, 0x836, METHOD_BUFFERED, FILE_WRITE_ACCESS
)
IOCTL_OLS_WRITE_IO_PORT_WORD = CTL_CODE(
    OLS_TYPE, 0x837, METHOD_BUFFERED, FILE_WRITE_ACCESS
)
IOCTL_OLS_WRITE_IO_PORT_DWORD = CTL_CODE(
    OLS_TYPE, 0x838, METHOD_BUFFERED, FILE_WRITE_ACCESS
)
IOCTL_OLS_READ_MEMORY = CTL_CODE(
    OLS_TYPE, 0x841, METHOD_BUFFERED, FILE_READ_ACCESS
)
IOCTL_OLS_WRITE_MEMORY = CTL_CODE(
    OLS_TYPE, 0x842, METHOD_BUFFERED, FILE_WRITE_ACCESS
)
IOCTL_OLS_READ_PCI_CONFIG = CTL_CODE(
    OLS_TYPE, 0x851, METHOD_BUFFERED, FILE_READ_ACCESS
)
IOCTL_OLS_WRITE_PCI_CONFIG = CTL_CODE(
    OLS_TYPE, 0x852, METHOD_BUFFERED, FILE_WRITE_ACCESS
)

#-----------------------------------------------------------------------------
#
# PCI Error Code
#
#-----------------------------------------------------------------------------
OLS_ERROR_PCI_BUS_NOT_EXIST = 0xE0000001
OLS_ERROR_PCI_NO_DEVICE     = 0xE0000002
OLS_ERROR_PCI_WRITE_CONFIG  = 0xE0000003
OLS_ERROR_PCI_READ_CONFIG   = 0xE0000004

#-----------------------------------------------------------------------------
#
# Support Macros
#
#-----------------------------------------------------------------------------

# Bus Number, Device Number and Function Number to PCI Device Address
def PciBusDevFunc(Bus, Dev, Func):
    return ((Bus & 0xFF) << 8) | ((Dev & 0x1F) << 3) | (Func & 7)
# PCI Device Address to Bus Number
def PciGetBus(address):
    return (address >> 8) & 0xFF
# PCI Device Address to Device Number
def PciGetDev(address):
    return (address >> 3) & 0x1F
# PCI Device Address to Function Number
def PciGetFunc(address):
    return address & 7

#-----------------------------------------------------------------------------
#
# Typedef Struct
#
#-----------------------------------------------------------------------------

class _OLS_WRITE_MSR_INPUT(Structure):
    _fields_ = [
        ("Register", ULONG),
        ("Value", ULARGE_INTEGER)
    ]
OLS_WRITE_MSR_INPUT = _OLS_WRITE_MSR_INPUT

class _DataValue(Union):
    _fields_ = [
        ("LongData", ULONG),
        ("ShortData", USHORT),
        ("CharData", UCHAR)
    ]

class _OLS_WRITE_IO_PORT_INPUT(Structure):
    _fields_ = [
        ("PortAddr", ULONG),
        ("DataValue", _DataValue)
    ]
OLS_WRITE_IO_PORT_INPUT = _OLS_WRITE_IO_PORT_INPUT

class _OLS_READ_PCI_CONFIG_INPUT(Structure):
    _fields_ = [
        ("PciAddress", ULONG),
        ("PciOffset", ULONG)
    ]
OLS_READ_PCI_CONFIG_INPUT = _OLS_READ_PCI_CONFIG_INPUT

class _OLS_WRITE_PCI_CONFIG_INPUT(Structure):
    _fields_ = [
        ("PciAddress", ULONG),
        ("PciOffset", ULONG),
        ("Data[1]", UCHAR)
    ]
OLS_WRITE_PCI_CONFIG_INPUT = _OLS_WRITE_PCI_CONFIG_INPUT

PHYSICAL_ADDRESS = LARGE_INTEGER

class _OLS_READ_MEMORY_INPUT(Structure):
    _fields_ = [
        ("Address", PHYSICAL_ADDRESS),
        ("UnitSize", ULONG),
        ("Count", ULONG)
    ]
OLS_READ_MEMORY_INPUT = _OLS_READ_MEMORY_INPUT

class _OLS_WRITE_MEMORY_INPUT(Structure):
    _fields_ = [
        ("Address", PHYSICAL_ADDRESS),
        ("UnitSize", ULONG),
        ("Count", ULONG),
        ("Data[1]", UCHAR)
    ]
OLS_WRITE_MEMORY_INPUT = _OLS_WRITE_MEMORY_INPUT



